#include "eigen/cross_entropy_loss.h"

namespace  ldl_eigen
{
float CrossEntropyLoss::forward(const Eigen::MatrixXf& inputs, 
                             const Eigen::MatrixXf& labels)
{
    input_ = inputs;
    labels_ = labels;
    
    // 数值稳定性处理 + 向量化计算
    constexpr float epsilon = 1e-15;
    Eigen::MatrixXf clipped = inputs.cwiseMax(epsilon).cwiseMin(1.0 - epsilon);
    return -(labels.array() * clipped.array().log()).sum();
}

Eigen::MatrixXf CrossEntropyLoss::backward() {
    constexpr float epsilon = 1e-15;
    output_ = -labels_.cwiseQuotient(
        input_.cwiseMax(epsilon).cwiseMin(1.0 - epsilon));
    return 1.0 / labels_.rows() * output_;
}
}